package com.btjava.maven.pomver.utils;

import com.btjava.maven.pomver.data.CommonData;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * xml 解析工具
 */
public class XmlParseUtils {
    /**
     * 获取xml文档对象
     * @param filePath
     * @return
     */
    public static Document getDocument(String filePath){
        File xmlFile = new File(filePath);
        SAXReader reader = new SAXReader();
        reader.setEncoding("UTF-8");
        Document doc = null;
        try {
            doc =reader.read(xmlFile);
        } catch (DocumentException e1) {
            e1.printStackTrace();
            return null;
        }
        if(Objects.isNull(doc)){
            return null;
        }
        return doc;
    }
    /**
     * 根据选择器路径获取节点
     * @param filePath xml路径
     * @param selectorPath 选择器路径
     * @return
     */
    public static List<Element> getElementByNamePath(String filePath,String selectorPath){
        Document doc = getDocument(filePath);
        if(Objects.isNull(doc)){
            return new ArrayList<>();
        }
        return getElementByNamePath(doc.getRootElement(),selectorPath);
    }

    /**
     * 根据选择器路径获取节点
     * @param root
     * @param selectorPath
     * @return
     */
    public static List<Element> getElementByNamePath(Element root,String selectorPath){
        String[] nameArr = selectorPath.split(">");
        List<Element> elementList =  new ArrayList<>();
        elementList.add(root);
        for(String selector :nameArr){
            if(Objects.isNull(elementList) || elementList.isEmpty()){
                return  new ArrayList<>();
            }
            if(selector.indexOf("[") >=0){
                elementList = getElementByAttr(elementList,selector.trim());
            }else{
                elementList = getElementByTag(elementList,selector.trim());
            }
        }
        return elementList;
    }

    /**
     * 根据标签名称获取节点
     * @param elementList
     * @param name
     * @return
     */
    private static List<Element> getElementByTag(List<Element> elementList,String name){
        List<Element> subList = getSubElement(elementList);
        if(Objects.isNull(subList) || subList.isEmpty()){
            return new ArrayList<>();
        }
        List<Element> resultList  = subList.stream().filter(one-> Objects.nonNull(one) &&
                name.equals(one.getName())).collect(Collectors.toList());
        return resultList;
    }

    /**
     * 根据节点属性获取节点
     * @param elementList
     * @param selector
     * @return
     */
    private static List<Element> getElementByAttr(List<Element> elementList,String selector){
        selector = selector.replace("[","").replace("]","");
        String [] arr = selector.split("=");
        String attr = arr[0];
        String value = arr.length >=2?arr[1]:"";
        List<Element> subList = getSubElement(elementList);
        if(Objects.isNull(subList) || subList.isEmpty()){
            return new ArrayList<>();
        }
        List<Element> resultList  = subList.stream().filter(one-> Objects.nonNull(one) &&
                value.equals(one.attributeValue(attr))).collect(Collectors.toList());
        return resultList;
    }

    private static List<Element> getSubElement(List<Element> elementList){
        List<Element> subList = new ArrayList<>();
        for(Element element :elementList){
            if(Objects.isNull(element)){
                continue;
            }
            List<Element> list = element.elements();
            if(Objects.nonNull(list) && !list.isEmpty()){
                subList.addAll(list);
            }
        }
        return subList;
    }

    public static void saveXml(Document doc,String filePath){
        System.out.println("pomVer("+DateTimeUtils.getCurrentTimeStr()+"):开始保存XML文件。");
        OutputFormat format = new OutputFormat();
        format.setEncoding("UTF-8");
        XMLWriter output = null;
        try {
            output = new XMLWriter(new FileOutputStream(filePath),format);
            output.write(doc);
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(Objects.nonNull(output)){
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        String refreshPath =  filePath.replace(CommonData.project.getBaseDir().getPath(),"");
        CommonData.project.getBaseDir().findFileByRelativePath(refreshPath).refresh(false,false);
    }
}
